/*!
 * \file jxbankc_message.c
 *
 * \brief JXBANKC消息解析
 * 
 * All Rights Reserved Copyright (C) 2014 broada,Co.,Ltd.
 *
 * \version 1.0
 * \author songbb
 * \date 2017/04/19
 *
 */

#include <iconv2utf8.h>
#include "conntrack.h"
#include "frct_comm.h"
#include "frreport_comm.h"

#include "jxbankc_core.h"
#include "jxbankc_comm.h"
#include "jxbankc_dict.h"
#include "jxbankc_message.h"
#include "jxbankc_interfaces.h"

Frhash_header *p_hash_jxbankc_workcode = NULL;

/*******************************************************************************
*  FUNC     :  释放 Jxbankc_workcode
*  ARGS     :  **pp_st_workcode                             (Jxbankc_workcode)
*  RTN      :  void
*  NOTE     :
*******************************************************************************/
FR_STATIC void __jxbankc_free_workcode(Jxbankc_workcode **pp_st_workcode)
{
    if (pp_st_workcode == NULL || *pp_st_workcode == NULL)
        return;

    jxbankc_free((void **) &((*pp_st_workcode)->p_name));
    jxbankc_free((void **) pp_st_workcode);

    return;
}

/*******************************************************************************
*  FUNC     :  释放 stmt node节点
*  ARGS     :  *p_st_node                               (Frlist_node)
*  RTN      :  void
*  NOTE     :
*******************************************************************************/
FR_STATIC void __jxbankc_workcode_node_free(Frlist_node *p_st_node)
{
    if (p_st_node == NULL || p_st_node->data == NULL)
        return;

    Jxbankc_workcode *p_st_sip_stmt = (Jxbankc_workcode *) FRLIST_GET_NODE_DATA(p_st_node);
    __jxbankc_free_workcode(&p_st_sip_stmt);
    p_st_node->data = NULL;
}

void jxbankc_init_hash_workcode(void)
{
    int len = sizeof(arr_jxbankc_workcode_maps) / sizeof(arr_jxbankc_workcode_maps[0]);
    int i_loop = 0;
    Jxbankc_workcode *p_st_workcode = NULL;
    Frlist_node *p_st_node = NULL;

    p_hash_jxbankc_workcode = frhash2_create2(len);

    for (; i_loop < len; i_loop++)
    {
        if ((p_st_workcode = (Jxbankc_workcode *) frmalloc(sizeof(Jxbankc_workcode))) == NULL)
        {
            JXBANKC_MALLOCK_ERR;
            return;
        }
        memset(p_st_workcode, 0x00, sizeof(Jxbankc_workcode));

        p_st_workcode->p_name = frstrdup(arr_jxbankc_workcode_maps[i_loop].arr_name);
        p_st_node = frlist_node_create(p_st_workcode);

        if (frhash2_addStr(p_hash_jxbankc_workcode, arr_jxbankc_workcode_maps[i_loop].arr_code,
                           (unsigned int) strlen(arr_jxbankc_workcode_maps[i_loop].arr_code), p_st_node) != FR_SUCC)
        {
            __jxbankc_free_workcode(&p_st_workcode);
            __jxbankc_workcode_node_free(p_st_node);
            return;
        }
    }

    return;
}

void jxbankc_destroy_hash_workcode(void)
{
    frhash2_free2(p_hash_jxbankc_workcode, __jxbankc_workcode_node_free);
    return;
}

FR_STATIC void __jxbankc_interface_node_free(Frlist_node *p_st_node)
{
    jxbankc_free(&(p_st_node->data));
    return;
}

FR_STATIC int __jxbankc_create_field_name(const char *p_prefix
                                        , const char *p_interface_name
                                        , const char *p_value
                                        , char **pp_field_name)
{
    char *p_field_name = NULL;
    int i_field_name_len = 0;

    int i_prefix_len = (int) (strlen(p_prefix) + strlen(p_interface_name)) + 1;

    i_field_name_len = i_prefix_len + (int) strlen(p_value) + 1;
    if ((p_field_name = (char *) frmalloc((i_field_name_len + 1) * sizeof(char))) == NULL)
    {
        JXBANKC_MALLOCK_ERR;
        goto error;
    }
    memset(p_field_name, 0x00, i_field_name_len + 1);
    snprintf(p_field_name, i_field_name_len, "%s%s.%s", p_prefix, p_interface_name, p_value);

    *pp_field_name = p_field_name;

    return FR_SUCC;
error:
    jxbankc_free((void **) &p_field_name);
    return FR_FAIL;
}

FR_STATIC int __jxbankc_get_value(L7_jxbankc_packet *p_st_jxbankc_packet
                                , int i_data_len
                                , char **pp_value)
{
    char *p_value = NULL;
    char *p_value_utf8 = NULL;
    unsigned int ui_value_utf8_len = 0;

    if ((p_value = (char *) frmalloc((i_data_len + 1) * sizeof(char))) == NULL)
    {
        JXBANKC_MALLOCK_ERR;
        goto error;
    }
    memset(p_value, 0x00, i_data_len);

    if (bytebuff_get_bytes(p_st_jxbankc_packet->p_st_packet, p_value, i_data_len) != FR_SUCC)
        goto error;
    p_value[i_data_len] = '\0';

    if (p_value[0] == '\0')
        *pp_value = p_value;
    else
    {
        if (iconv_to_utf8(p_value, strlen(p_value), "gb18030", &p_value_utf8, &ui_value_utf8_len) != FR_SUCC)
            goto error;
        jxbankc_free((void **) &p_value);
        frtrim(p_value_utf8);

        *pp_value = p_value_utf8;
    }

    return FR_SUCC;
error:
    jxbankc_free((void **) &p_value);
    return FR_FAIL;
}

FR_STATIC int __jxbankc_parse_interface(L7_jxbankc_packet *p_st_jxbankc_packet
                                        , Frreport_body_data *p_st_body
                                        , const char *p_prefix
                                        , const char *p_interface_name
                                        , Jxbankc_interface_map *arr_interface_map
                                        , int i_map_len)
{
    char *p_field_name = NULL;
    char *p_value = NULL;
    int i_loop = 0;

    for (; i_loop < i_map_len; i_loop++)
    {
        if (__jxbankc_create_field_name(p_prefix, p_interface_name, arr_interface_map[i_loop].arr_field_name,
                                        &p_field_name) != FR_SUCC)
            goto error;

        if (__jxbankc_get_value(p_st_jxbankc_packet, arr_interface_map[i_loop].i_field_len, &p_value) != FR_SUCC)
            goto error;
        JXBANKC_PRINT_CRIT("[%s] = [%s]\n", p_field_name, p_value);

        if (frreport_body_l7_add_str(p_st_body, p_field_name, p_value) != FR_SUCC)
            goto error;

        jxbankc_free((void **) &p_field_name);
        jxbankc_free((void **) &p_value);
    }

    return FR_SUCC;
error:
    jxbankc_free((void **) &p_field_name);
    jxbankc_free((void **) &p_value);
    return FR_FAIL;
}

FR_STATIC int __jxbankc_parse_body(Frlist_header *p_list_interfaces
                                , L7_jxbankc_packet *p_st_jxbankc_packet
                                , Frreport_body_data *p_st_body
                                , const char *p_prefix)
{
    Frlist_node *p_st_node = NULL;
    Jxbankc_interface *p_st_interface = NULL;
    int i_loop = 0;

    bytebuff_setPosition(p_st_jxbankc_packet->p_st_packet, p_st_jxbankc_packet->st_jxbankc_header.ui_header_len);

    p_st_node = FRLIST_FIRST_NODE(p_list_interfaces);
    while (p_st_node)
    {
        p_st_interface = (Jxbankc_interface *) FRLIST_GET_NODE_DATA(p_st_node);

        for (i_loop = 0; i_loop < p_st_interface->i_data_num; i_loop++)
        {
            if (strcmp(p_st_interface->arr_name, "gsreqroot") == 0)
            {
                if (__jxbankc_parse_interface(p_st_jxbankc_packet, p_st_body, p_prefix, "gsreqroot",
                                            arr_jxbankc_interface_gsreqroot_maps,
                                            sizeof(arr_jxbankc_interface_gsreqroot_maps) / sizeof(arr_jxbankc_interface_gsreqroot_maps[0])) != FR_SUCC)
                    goto error;
            }
            else if (strcmp(p_st_interface->arr_name, "gsrsproot") == 0)
            {
                if (__jxbankc_parse_interface(p_st_jxbankc_packet, p_st_body, p_prefix, "gsrsproot",
                                            arr_jxbankc_interface_gsrsproot_maps,
                                            sizeof(arr_jxbankc_interface_gsrsproot_maps) / sizeof(arr_jxbankc_interface_gsrsproot_maps[0])) != FR_SUCC)
                    goto error;
            }
            else if (strcmp(p_st_interface->arr_name, "gsrspmsg") == 0)
            {
                if (__jxbankc_parse_interface(p_st_jxbankc_packet, p_st_body, p_prefix, "gsrspmsg",
                                            arr_jxbankc_interface_gsrspmsg_maps,
                                            sizeof(arr_jxbankc_interface_gsrspmsg_maps) / sizeof(arr_jxbankc_interface_gsrspmsg_maps[0])) != FR_SUCC)
                    goto error;
            }
            else if (strcmp(p_st_interface->arr_name, "gsiflow") == 0)
            {
                if (__jxbankc_parse_interface(p_st_jxbankc_packet, p_st_body, p_prefix, "gsiflow",
                                            arr_jxbankc_interface_gsiflow_maps,
                                            sizeof(arr_jxbankc_interface_gsiflow_maps) / sizeof(arr_jxbankc_interface_gsiflow_maps[0])) != FR_SUCC)
                    goto error;
            }
            else if (strcmp(p_st_interface->arr_name, "gsreqspots") == 0)
            {
                if (__jxbankc_parse_interface(p_st_jxbankc_packet, p_st_body, p_prefix, "gsreqspots",
                                            arr_jxbankc_interface_gsreqspots_maps,
                                            sizeof(arr_jxbankc_interface_gsreqspots_maps) / sizeof(arr_jxbankc_interface_gsreqspots_maps[0])) != FR_SUCC)
                    goto error;
            }
            else if (strcmp(p_st_interface->arr_name, "pnctl") == 0)
            {
                if (__jxbankc_parse_interface(p_st_jxbankc_packet, p_st_body, p_prefix, "pnctl",
                                            arr_jxbankc_interface_pnctl_maps,
                                            sizeof(arr_jxbankc_interface_pnctl_maps) / sizeof(arr_jxbankc_interface_pnctl_maps[0])) != FR_SUCC)
                    goto error;
            }
            else if (strcmp(p_st_interface->arr_name, "rt_booktrans") == 0)
            {
                if (__jxbankc_parse_interface(p_st_jxbankc_packet, p_st_body, p_prefix, "rt_booktrans",
                                            arr_jxbankc_interface_rt_booktrans_maps,
                                            sizeof(arr_jxbankc_interface_rt_booktrans_maps) / sizeof(arr_jxbankc_interface_rt_booktrans_maps[0])) != FR_SUCC)
                    goto error;
            }
            else if (strcmp(p_st_interface->arr_name, "rcocxwdw") == 0)
            {
                if (__jxbankc_parse_interface(p_st_jxbankc_packet, p_st_body, p_prefix, "rcocxwdw",
                                            arr_jxbankc_interface_rcocxwdw_maps,
                                            sizeof(arr_jxbankc_interface_rcocxwdw_maps) / sizeof(arr_jxbankc_interface_rcocxwdw_maps[0])) != FR_SUCC)
                    goto error;
            }
            else if (strcmp(p_st_interface->arr_name, "rcocxbook") == 0)
            {
                if (__jxbankc_parse_interface(p_st_jxbankc_packet, p_st_body, p_prefix, "rcocxbook",
                                            arr_jxbankc_interface_rcocxbook_maps,
                                            sizeof(arr_jxbankc_interface_rcocxbook_maps) / sizeof(arr_jxbankc_interface_rcocxbook_maps[0])) != FR_SUCC)
                    goto error;
            }
            else if (strcmp(p_st_interface->arr_name, "rc_feeset") == 0)
            {
                if (__jxbankc_parse_interface(p_st_jxbankc_packet, p_st_body, p_prefix, "rc_feeset",
                                            arr_jxbankc_interface_rc_feeset_maps,
                                            sizeof(arr_jxbankc_interface_rc_feeset_maps) / sizeof(arr_jxbankc_interface_rc_feeset_maps[0])) != FR_SUCC)
                    goto error;
            }
            else if (strcmp(p_st_interface->arr_name, "rc_feedtl") == 0)
            {
                if (__jxbankc_parse_interface(p_st_jxbankc_packet, p_st_body, p_prefix, "rc_feedtl",
                                            arr_jxbankc_interface_rc_feedtl_maps,
                                            sizeof(arr_jxbankc_interface_rc_feedtl_maps) / sizeof(arr_jxbankc_interface_rc_feedtl_maps[0])) != FR_SUCC)
                    goto error;
            }
            else
            {
                JXBANKC_PRINT_ALERT("interface of %s not defined, skip %d\n", p_st_interface->arr_name, p_st_interface->i_data_len);
                if (bytebuff_skip(p_st_jxbankc_packet->p_st_packet, p_st_interface->i_data_len) != FR_SUCC)
                    goto error;
            }
        }

        p_st_node = FRLIST_NEXT_NODE(p_st_node);
    }

    return FR_SUCC;
error:
    return FR_FAIL;
}

int jxbankc_req(Conntrack *p_st_conn
                , L7session_jxbankc *p_st_sess
                , L7_jxbankc_packet *p_st_jxbankc_packet
                , Frhash_header *p_st_hash_report)
{
    JXBANKC_PRINT_INFO("jxbankc_req...\n");
    Frreport_body_data *p_st_body = NULL;
    uint8_t uc_tmp = 0;
    char arr_interface_len[6+1] = {0};
    char arr_interface_num[5+1] = {0};
    int i_gsreqroot_data_offset = p_st_jxbankc_packet->st_jxbankc_header.ui_header_len;
    int i_found_gsreqroot = FR_NO;
    char arr_comreq[20+1] = {0};
    char arr_channel[3+1] = {0};
    char arr_workcode[8+1] = {0};
    Jxbankc_workcode *p_st_workcode = NULL;
    Frlist_node *p_st_node = NULL;
    Frlist_header *p_list_interfaces = NULL;
    Jxbankc_interface *p_st_interface = NULL;

    if (bytebuff_skip(p_st_jxbankc_packet->p_st_packet, 36) != FR_SUCC)
        goto error;

    p_list_interfaces = frlist_create();

    while (bytebuff_getPosition(p_st_jxbankc_packet->p_st_packet) < (int) p_st_jxbankc_packet->st_jxbankc_header.ui_header_len)
    {
        if (bytebuff_peek_char(p_st_jxbankc_packet->p_st_packet, &uc_tmp) != FR_SUCC)
            goto error;

        if (uc_tmp == 0x00)
            break;

        if ((p_st_interface = (Jxbankc_interface *) frmalloc(sizeof(Jxbankc_interface))) == NULL)
        {
            JXBANKC_MALLOCK_ERR;
            goto error;
        }
        memset(p_st_interface, 0x00, sizeof(Jxbankc_interface));

        if (bytebuff_get_bytes(p_st_jxbankc_packet->p_st_packet, p_st_interface->arr_name, 20) != FR_SUCC)
            goto error;
        JXBANKC_PRINT_WARN("req interface_name:[%s]\n", p_st_interface->arr_name);

        memset(arr_interface_len, 0x00, sizeof(arr_interface_len));
        if (bytebuff_get_bytes(p_st_jxbankc_packet->p_st_packet, arr_interface_len, 6) != FR_SUCC)
            goto error;
        p_st_interface->i_data_len = atoi(arr_interface_len);
        JXBANKC_PRINT_WARN("req interface_len:[%d]\n", p_st_interface->i_data_len);

        memset(arr_interface_num, 0x00, sizeof(arr_interface_num));
        if (bytebuff_get_bytes(p_st_jxbankc_packet->p_st_packet, arr_interface_num, 5) != FR_SUCC)
            goto error;
        p_st_interface->i_data_num = atoi(arr_interface_num);
        JXBANKC_PRINT_WARN("req interface_num:[%d]\n", p_st_interface->i_data_num);

        if (strcmp(p_st_interface->arr_name, "gsreqroot") == 0)
            i_found_gsreqroot = FR_YES;

        if (i_found_gsreqroot == FR_NO)
            i_gsreqroot_data_offset += p_st_interface->i_data_len * p_st_interface->i_data_num;

        p_st_node = frlist_node_create(p_st_interface);

        frlist_push(p_list_interfaces, p_st_node);
        p_st_interface = NULL;
    }

    if (i_found_gsreqroot == FR_NO)
        i_gsreqroot_data_offset = 0;

    JXBANKC_PRINT_DBG("req gsreqroot offset:[%d]\n", i_gsreqroot_data_offset);

    if (i_found_gsreqroot == FR_YES)
    {
        bytebuff_setPosition(p_st_jxbankc_packet->p_st_packet, i_gsreqroot_data_offset);
        memset(arr_comreq, 0x00, sizeof(arr_comreq));
        if (bytebuff_get_bytes(p_st_jxbankc_packet->p_st_packet, arr_comreq, 20) != FR_SUCC)
            goto error;
        JXBANKC_PRINT_CRIT("req comreq:[%s]\n", arr_comreq);

        bytebuff_setPosition(p_st_jxbankc_packet->p_st_packet, i_gsreqroot_data_offset + 22);
        memset(arr_channel, 0x00, sizeof(arr_channel));
        if (bytebuff_get_bytes(p_st_jxbankc_packet->p_st_packet, arr_channel, 3) != FR_SUCC)
            goto error;
        JXBANKC_PRINT_CRIT("channel:[%s]\n", arr_channel);

        bytebuff_setPosition(p_st_jxbankc_packet->p_st_packet, i_gsreqroot_data_offset + 27);
        memset(arr_workcode, 0x00, sizeof(arr_workcode));
        if (bytebuff_get_bytes(p_st_jxbankc_packet->p_st_packet, arr_workcode, 8) != FR_SUCC)
            goto error;
        JXBANKC_PRINT_CRIT("workcode:[%s]\n", arr_workcode);
    }

    if (arr_workcode[0] != 0x00)
    {
        // 新建上报数据结构体
        if ((p_st_body = frreport_body_new_l7(p_st_conn)) == NULL)
            goto error;

        if (__jxbankc_parse_body(p_list_interfaces, p_st_jxbankc_packet, p_st_body, "request.jxbankc.") != FR_SUCC)
            goto error;

        if (frreport_body_l7_add_str(p_st_body, APM_REPORT_KEY_TRANS".type_code", arr_workcode) != FR_SUCC)
            goto error;

        p_st_node = frhash2_getStr(p_hash_jxbankc_workcode, arr_workcode, (unsigned int) strlen(arr_workcode));
        if (p_st_node && (p_st_workcode = (Jxbankc_workcode *) FRLIST_GET_NODE_DATA(p_st_node)) == NULL)
            goto error;
        if (p_st_workcode && p_st_workcode->p_name)
        {
            if (frreport_body_l7_add_str(p_st_body, APM_REPORT_KEY_TRANS_TITLE, p_st_workcode->p_name) != FR_SUCC)
                goto error;
            if (frreport_body_l7_add_str(p_st_body, APM_REPORT_KEY_TRANS".type_name", p_st_workcode->p_name) != FR_SUCC)
                goto error;
        }
        else
        {
            if (frreport_body_l7_add_str(p_st_body, APM_REPORT_KEY_TRANS_TITLE, arr_workcode) != FR_SUCC)
                goto error;
            if (frreport_body_l7_add_str(p_st_body, APM_REPORT_KEY_TRANS".type_name", arr_workcode) != FR_SUCC)
                goto error;
        }

        if (arr_comreq[0] != 0x00)
        {
            if (frreport_body_l7_add_str(p_st_body, APM_REPORT_KEY_TRANS".code", arr_comreq) != FR_SUCC)
                goto error;
        }

        if (arr_channel[0] != 0x00)
        {
            if (frreport_body_l7_add_str(p_st_body, APM_REPORT_KEY_TRANS".channel_code", arr_channel) != FR_SUCC)
                goto error;
            if (frreport_body_l7_add_str(p_st_body, APM_REPORT_KEY_TRANS".channel_name", arr_channel) != FR_SUCC)
                goto error;
        }

            // 上报数据
        if (jxbankc_report_msg_data_req(p_st_conn, p_st_jxbankc_packet, p_st_body, p_st_hash_report) != FR_SUCC)
            goto error;
    }

    frlist_destroy(p_list_interfaces, __jxbankc_interface_node_free);
    return FR_SUCC;
error:
    jxbankc_free((void **) &p_st_interface);
    frlist_destroy(p_list_interfaces, __jxbankc_interface_node_free);
    frreport_body_free(&p_st_body);
    return FR_FAIL;
}

int jxbankc_resp(Conntrack *p_st_conn
                , L7session_jxbankc *p_st_sess
                , L7_jxbankc_packet *p_st_jxbankc_packet
                , Frhash_header *p_st_hash_report)
{
    JXBANKC_PRINT_INFO("jxbankc_resp...\n");
    Frreport_body_data *p_st_body = NULL;
    uint8_t uc_tmp = 0;
    char arr_interface_len[6+1] = {0};
    char arr_interface_num[5+1] = {0};
    int i_gsrsproot_data_offset = p_st_jxbankc_packet->st_jxbankc_header.ui_header_len;
    int i_gsrspmsg_data_offset = p_st_jxbankc_packet->st_jxbankc_header.ui_header_len;
    int i_found_gsrsproot = FR_NO;
    int i_found_gsrspmsg = FR_NO;
    char arr_comreq[20+1] = {0};
    char arr_msgcode[7+1] = {0};
    char arr_msglevel[2+1] = {0};
    char arr_msgtext[192+1] = {0};
    char *p_msgtext = NULL;
    unsigned int ui_msgtext_len = 0;
    Frlist_node *p_st_node = NULL;
    Frlist_header *p_list_interfaces = NULL;
    Jxbankc_interface *p_st_interface = NULL;

    if (bytebuff_skip(p_st_jxbankc_packet->p_st_packet, 36) != FR_SUCC)
        goto error;

    p_list_interfaces = frlist_create();

    while (bytebuff_getPosition(p_st_jxbankc_packet->p_st_packet) < (int) p_st_jxbankc_packet->st_jxbankc_header.ui_header_len)
    {
        if (bytebuff_peek_char(p_st_jxbankc_packet->p_st_packet, &uc_tmp) != FR_SUCC)
            goto error;

        if (uc_tmp == 0x00)
            break;

        if ((p_st_interface = (Jxbankc_interface *) frmalloc(sizeof(Jxbankc_interface))) == NULL)
        {
            JXBANKC_MALLOCK_ERR;
            goto error;
        }
        memset(p_st_interface, 0x00, sizeof(Jxbankc_interface));

        if (bytebuff_get_bytes(p_st_jxbankc_packet->p_st_packet, p_st_interface->arr_name, 20) != FR_SUCC)
            goto error;
        JXBANKC_PRINT_WARN("resp interface_name:[%s]\n", p_st_interface->arr_name);

        memset(arr_interface_len, 0x00, sizeof(arr_interface_len));
        if (bytebuff_get_bytes(p_st_jxbankc_packet->p_st_packet, arr_interface_len, 6) != FR_SUCC)
            goto error;
        p_st_interface->i_data_len = atoi(arr_interface_len);
        JXBANKC_PRINT_WARN("resp interface_len:[%d]\n", p_st_interface->i_data_len);

        memset(arr_interface_num, 0x00, sizeof(arr_interface_num));
        if (bytebuff_get_bytes(p_st_jxbankc_packet->p_st_packet, arr_interface_num, 5) != FR_SUCC)
            goto error;
        p_st_interface->i_data_num = atoi(arr_interface_num);
        JXBANKC_PRINT_WARN("resp interface_num:[%d]\n", p_st_interface->i_data_num);

        if (strcmp(p_st_interface->arr_name, "gsrsproot") == 0)
        {
            i_found_gsrsproot = FR_YES;
        }
        else if (strcmp(p_st_interface->arr_name, "gsrspmsg") == 0)
        {
            i_found_gsrspmsg = FR_YES;
        }

        if (i_found_gsrsproot == FR_NO)
            i_gsrsproot_data_offset += p_st_interface->i_data_len * p_st_interface->i_data_num;
        if (i_found_gsrspmsg == FR_NO)
            i_gsrspmsg_data_offset += p_st_interface->i_data_len * p_st_interface->i_data_num;

        p_st_node = frlist_node_create(p_st_interface);

        frlist_push(p_list_interfaces, p_st_node);
        p_st_interface = NULL;
    }

    if (i_found_gsrsproot == FR_NO)
        i_gsrsproot_data_offset = 0;
    if (i_found_gsrspmsg == FR_NO)
        i_gsrspmsg_data_offset = 0;

    JXBANKC_PRINT_DBG("resp gsrsproot offset:[%d]\n", i_gsrsproot_data_offset);
    JXBANKC_PRINT_DBG("resp gsrspmsg offset:[%d]\n", i_gsrspmsg_data_offset);

    if (i_found_gsrsproot == FR_YES)
    {
        bytebuff_setPosition(p_st_jxbankc_packet->p_st_packet, i_gsrsproot_data_offset);
        memset(arr_comreq, 0x00, sizeof(arr_comreq));
        if (bytebuff_get_bytes(p_st_jxbankc_packet->p_st_packet, arr_comreq, 20) != FR_SUCC)
            goto error;
        JXBANKC_PRINT_CRIT("resp comreq:[%s]\n", arr_comreq);

        bytebuff_setPosition(p_st_jxbankc_packet->p_st_packet, i_gsrsproot_data_offset + 20);
        memset(arr_msgcode, 0x00, sizeof(arr_msgcode));
        if (bytebuff_get_bytes(p_st_jxbankc_packet->p_st_packet, arr_msgcode, 7) != FR_SUCC)
            goto error;
        JXBANKC_PRINT_CRIT("msgcode:[%s]\n", arr_msgcode);

        bytebuff_setPosition(p_st_jxbankc_packet->p_st_packet, i_gsrsproot_data_offset + 27);
        memset(arr_msglevel, 0x00, sizeof(arr_msglevel));
        if (bytebuff_get_bytes(p_st_jxbankc_packet->p_st_packet, arr_msglevel, 2) != FR_SUCC)
            goto error;
        JXBANKC_PRINT_CRIT("msglevel:[%s]\n", arr_msglevel);
    }

    if (i_found_gsrspmsg == FR_YES)
    {
        bytebuff_setPosition(p_st_jxbankc_packet->p_st_packet, i_gsrspmsg_data_offset);
        memset(arr_msgtext, 0x00, sizeof(arr_msgtext));
        if (bytebuff_get_bytes(p_st_jxbankc_packet->p_st_packet, arr_msgtext, 192) != FR_SUCC)
            goto error;
        if (iconv_to_utf8(arr_msgtext, strlen(arr_msgtext), "gb18030", &p_msgtext, &ui_msgtext_len) != FR_SUCC)
            goto error;
        JXBANKC_PRINT_CRIT("msgtext:[%s]\n", p_msgtext);
    }

    if (arr_msgcode[0] != 0x00)
    {
        // 新建上报数据结构体
        if ((p_st_body = frreport_body_new_l7(p_st_conn)) == NULL)
            goto error;

        if (__jxbankc_parse_body(p_list_interfaces, p_st_jxbankc_packet, p_st_body, "response.jxbankc.") != FR_SUCC)
            goto error;

        if (frreport_body_l7_add_str(p_st_body, APM_REPORT_KEY_RESP_CODE_STRING, arr_msgcode) != FR_SUCC)
            goto error;
        if (arr_msgtext[0] != 0x00)
        {
            if (frreport_body_l7_add_str(p_st_body, APM_REPORT_KEY_RESP_ERR_MSG, p_msgtext) != FR_SUCC)
                goto error;
        }

        // 上报数据
        if (jxbankc_report_msg_data_resp(p_st_conn, p_st_jxbankc_packet, p_st_body, p_st_hash_report) != FR_SUCC)
            goto error;
    }

    frlist_destroy(p_list_interfaces, __jxbankc_interface_node_free);
    jxbankc_free((void **) &p_msgtext);
    return FR_SUCC;
error:
    jxbankc_free((void **) &p_st_interface);
    frlist_destroy(p_list_interfaces, __jxbankc_interface_node_free);
    jxbankc_free((void **) &p_msgtext);
    frreport_body_free(&p_st_body);
    return FR_FAIL;
}
